package com.pipayshop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pipayshop.config.OrderQueueConfig;
import com.pipayshop.domain.*;
import com.pipayshop.domain.dto.GetOrderByNameDto;
import com.pipayshop.domain.dto.GetOrderDataDto;
import com.pipayshop.domain.dto.ShopOrderDetailDTO;
import com.pipayshop.domain.vo.ShopOrderDetailVO;
import com.pipayshop.domain.vo.ShopOrderInfoVO;
import com.pipayshop.entity.BuyerData;
import com.pipayshop.exception.BusinessException;
import com.pipayshop.mapper.*;
import com.pipayshop.service.OnlineStoreShopOrderInfoService;
import com.pipayshop.utils.Constants;
import com.pipayshop.utils.StringUtil;
import com.pipayshop.utils.TokenUtil;
import com.pipayshop.utils.ValidationUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiaoqiu
 * @date 2024/10/8 11:32
 * @description
 */
@Service
@Slf4j
public class OnlineStoreShopOrderInfoServiceImpl extends ServiceImpl<OnlineStoreShopOrderInfoMapper, ShopOrderInfo> implements OnlineStoreShopOrderInfoService {

    private static final String ERROR_MAG = "generate_order_failed";
    private static final String PAY_ERROR = "order_already_paid";
    @Autowired
    private OnlineStoreOrderMapper shopOrderMapper;
    @Autowired
    private OnlineStoreShopMapper shopMapper;
    @Autowired
    private OnlineStoreShopOrderDetailMapper shopOrderDetailMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private UserAccountInfoMapper accountInfoMapper;
    @Autowired
    private OnlineStoreShopOrderInfoMapper shopOrderInfoMapper;
    @Autowired
    private OnlineStoreSkuMapper skuMapper;
    @Autowired
    private BuyerDataMapper buyerDataMapper;
    @Autowired
    private OnlineStoreShopCommodityMapper shopCommodityMapper;
    @Autowired
    private ImageMapper imageMapper;
    @Autowired
    private OnlineStoreShopCartMapper shopCartMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Cacheable(value = Constants.SHOP_ORDER_LIST_KEY, key = "#getOrderDataDto.userId+#getOrderDataDto.shopId+#getOrderDataDto.orderStatus+#getOrderDataDto.start+#getOrderDataDto.size")
    @Override
    public List<ShopOrderInfoVO> getOrderList(GetOrderDataDto getOrderDataDto) {
        List<Integer> status = getOrderDataDto.getOrderStatus();
        String userId = getOrderDataDto.getUserId();
        String shopId = getOrderDataDto.getShopId();
        Long size = getOrderDataDto.getSize();
        Long start = getOrderDataDto.getStart();
        Page<ShopOrder> page = new Page<>(start, size);
        // 获取订单列表
        Page<ShopOrder> shopOrdersPage = (status.get(0) != -1) ?
                shopOrderMapper.selectPage(page, new LambdaQueryWrapper<ShopOrder>()
                        .in(ShopOrder::getOrderStatus, status)
                        .eq(StringUtils.isNotEmpty(userId), ShopOrder::getUid, userId)
                        .eq(ShopOrder::getDelFlag, 0)
                        .eq(StringUtils.isNotEmpty(shopId), ShopOrder::getShopId, shopId)
                        .orderByDesc(ShopOrder::getCreateTime)
                )
                :
                shopOrderMapper.selectPage(page, new LambdaQueryWrapper<ShopOrder>()
                        .in(StringUtils.isNotEmpty(userId), ShopOrder::getUid, userId)
                        .eq(ShopOrder::getDelFlag, 0)
                        .eq(StringUtils.isNotEmpty(shopId), ShopOrder::getShopId, shopId)
                        .orderByDesc(ShopOrder::getCreateTime));

        // 提取 shopIds 和 shopOrdersIds
        List<String> shopIds = new ArrayList<>();
        List<String> shopOrdersIds = new ArrayList<>();
        List<ShopOrder> shopOrders = shopOrdersPage.getRecords();
        for (ShopOrder shopOrder : shopOrders) {
            shopIds.add(shopOrder.getShopId());
            shopOrdersIds.add(shopOrder.getOrderId());
        }
        List<ShopOrderInfoVO> shopOrderInfoVOS = new ArrayList<>();

        if (shopIds.size() == 0) {
            return shopOrderInfoVOS;
        }

        // 查询店铺和订单详情
        List<Shop> shops = shopMapper.selectList(
                new LambdaQueryWrapper<Shop>().in(Shop::getShopId, shopIds));
        List<ShopOrderDetail> shopOrderDetails = shopOrderDetailMapper.selectList(
                new LambdaQueryWrapper<ShopOrderDetail>().in(ShopOrderDetail::getOrderId, shopOrdersIds));
        List<ShopCommodity> shopCommodities = shopCommodityMapper.selectList(
                new LambdaQueryWrapper<ShopCommodity>().in(ShopCommodity::getShopId, shopIds)
        );


        for (ShopCommodity shopCommodity : shopCommodities) {
            String imagePath = imageMapper.selectPath(shopCommodity.getAvatarImg());
            shopCommodity.setAvatarImg(imagePath);
        }

        for (ShopOrderDetail shopOrderDetail : shopOrderDetails) {
            for (ShopCommodity shopCommodity : shopCommodities) {
                if (shopCommodity.getCommodityId().equals(shopOrderDetail.getCommodityId())) {
                    shopOrderDetail.setAvatarImg(shopCommodity.getAvatarImg());
                    // 设置商品名称
                    shopOrderDetail.setCommodityName(shopCommodity.getCommodityName());
                    //设置商品规格
                    System.err.println(shopOrderDetail.getCommoditySpecification());
//                    shopOrderDetail.setCommoditySpecification(shopOrderDetail.getCommoditySpecification());
                }
            }
        }

// 使用 Map 映射 shopId 和 orderId，提高查找效率
        Map<String, String> shopNameMap = shops.stream()
                .collect(Collectors.toMap(Shop::getShopId, Shop::getShopName));

        Map<String, List<ShopOrderDetail>> orderDetailMap = shopOrderDetails.stream()
                .collect(Collectors.groupingBy(ShopOrderDetail::getOrderId));


        // 转换为 VO 并设置店铺名和订单详情
        shopOrderInfoVOS = BeanUtil.copyToList(shopOrders, ShopOrderInfoVO.class);
        //如果HashMap中包含shopid，则不用查询数据库
        HashMap<String, String> shopids = new HashMap<>();
        String url = null;
        for (ShopOrderInfoVO shopOrderInfoVO : shopOrderInfoVOS) {
            if (shopids.containsKey(shopOrderInfoVO.getShopId())) {
                url = shopids.get(shopOrderInfoVO.getShopId());
            } else {
                url = shopMapper.selectUrl(shopOrderInfoVO.getShopId());
                shopids.put(shopOrderInfoVO.getShopId(), url);
            }
            // 设置店铺名
            String shopName = shopNameMap.get(shopOrderInfoVO.getShopId());


            shopOrderInfoVO.setShopName(shopName);
            shopOrderInfoVO.setShopUrl(url);


            // 设置订单详情列表
            List<ShopOrderDetail> shopOrderDetailsList = orderDetailMap.getOrDefault(shopOrderInfoVO.getOrderId(), new ArrayList<>());
            shopOrderInfoVO.setShopOrderDetail(shopOrderDetailsList);

            // 检查并初始化 imagsList
            if (shopOrderInfoVO.getImagsList() == null) {
                shopOrderInfoVO.setImagsList(new ArrayList<>());
            }

            List<ShopOrderDetail> shopOrderDetail = shopOrderInfoVO.getShopOrderDetail();
            if (shopOrderDetail != null) {
                for (ShopOrderDetail orderDetail : shopOrderDetail) {
                    String avatarImg = orderDetail.getAvatarImg();
                    shopOrderInfoVO.getImagsList().add(avatarImg);
                }
            }
        }
        //根据订单创建时间正序排列
        shopOrderInfoVOS.sort(Comparator.comparing(ShopOrderInfoVO::getUpdateTime).reversed());
        return shopOrderInfoVOS;
    }

    @Override
    public List<ShopOrderInfoVO> getOrderListByItemName(GetOrderByNameDto getOrderByNameDto) {
        List<Integer> status = getOrderByNameDto.getOrderStatus();
        String userId = getOrderByNameDto.getUserId();
        String commodityName = getOrderByNameDto.getCommodityName();

        // 查询商品ID列表，使用商品名称进行模糊查询
        List<ShopCommodity> shopCommodities = shopCommodityMapper.selectList(
                new LambdaQueryWrapper<ShopCommodity>()
                        .like(StringUtils.isNotEmpty(commodityName), ShopCommodity::getCommodityName, commodityName)
        );

        if (shopCommodities.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取商品ID列表
        List<String> commodityIds = shopCommodities.stream()
                .map(ShopCommodity::getCommodityId)
                .collect(Collectors.toList());

        // 查询订单详情，找到所有包含目标商品ID的订单
        List<ShopOrderDetail> shopOrderDetails = shopOrderDetailMapper.selectList(
                new LambdaQueryWrapper<ShopOrderDetail>()
                        .in(ShopOrderDetail::getCommodityId, commodityIds)
        );

        // 获取所有关联的订单ID
        List<String> orderIds = shopOrderDetails.stream()
                .map(ShopOrderDetail::getOrderId)
                .distinct()
                .collect(Collectors.toList());

        if (orderIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 查询符合条件的订单列表
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<ShopOrder>()
                .in(ShopOrder::getOrderId, orderIds) // 使用找到的订单ID
                .in(status != null && !status.isEmpty() && status.get(0) != -1, ShopOrder::getOrderStatus, status)
                .eq(StringUtils.isNotEmpty(userId), ShopOrder::getUid, userId);

        List<ShopOrder> shopOrders = shopOrderMapper.selectList(queryWrapper);

        // 提取符合条件的 shopId
        List<String> shopIds = shopOrders.stream()
                .map(ShopOrder::getShopId)
                .distinct()
                .collect(Collectors.toList());

        // 查询店铺信息
        List<Shop> shops = shopMapper.selectList(
                new LambdaQueryWrapper<Shop>().in(Shop::getShopId, shopIds)
        );

        // 获取商品的图片路径
        for (ShopCommodity shopCommodity : shopCommodities) {
            String imagePath = imageMapper.selectPath(shopCommodity.getAvatarImg());
            shopCommodity.setAvatarImg(imagePath);
        }

        // 使用 Map 映射 shopId 和 shopName，提高查找效率
        Map<String, String> shopNameMap = shops.stream()
                .collect(Collectors.toMap(Shop::getShopId, Shop::getShopName));

        // 使用 Map 映射 orderId 和 orderDetails
        Map<String, List<ShopOrderDetail>> orderDetailMap = shopOrderDetails.stream()
                .collect(Collectors.groupingBy(ShopOrderDetail::getOrderId));

        // 将商品名称和图片赋给订单详情
        for (ShopOrderDetail orderDetail : shopOrderDetails) {
            for (ShopCommodity shopCommodity : shopCommodities) {
                if (shopCommodity.getCommodityId().equals(orderDetail.getCommodityId())) {
                    orderDetail.setCommodityName(shopCommodity.getCommodityName());
                    orderDetail.setAvatarImg(shopCommodity.getAvatarImg());
                }
            }
        }

        // 转换为 VO 并设置店铺名和订单详情
        List<ShopOrderInfoVO> shopOrderInfoVOS = BeanUtil.copyToList(shopOrders, ShopOrderInfoVO.class);
        HashMap<String, String> shopUrlCache = new HashMap<>();
        for (ShopOrderInfoVO shopOrderInfoVO : shopOrderInfoVOS) {
            // 设置店铺 URL，避免多次查询
            String url = shopUrlCache.getOrDefault(shopOrderInfoVO.getShopId(),
                    shopMapper.selectUrl(shopOrderInfoVO.getShopId()));
            shopUrlCache.put(shopOrderInfoVO.getShopId(), url);

            // 设置店铺名称
            String shopName = shopNameMap.get(shopOrderInfoVO.getShopId());
            shopOrderInfoVO.setShopName(shopName);
            shopOrderInfoVO.setShopUrl(url);

            // 设置订单详情列表
            List<ShopOrderDetail> shopOrderDetailsList = orderDetailMap.getOrDefault(shopOrderInfoVO.getOrderId(), new ArrayList<>());
            shopOrderInfoVO.setShopOrderDetail(shopOrderDetailsList);

            // 检查并初始化 imagesList
            if (shopOrderInfoVO.getImagsList() == null) {
                shopOrderInfoVO.setImagsList(new ArrayList<>());
            }

            // 将商品图片加入到 imagsList 中
            for (ShopOrderDetail orderDetail : shopOrderInfoVO.getShopOrderDetail()) {
                shopOrderInfoVO.getImagsList().add(orderDetail.getAvatarImg());
            }
        }

        // 根据订单更新时间倒序排列
        shopOrderInfoVOS.sort(Comparator.comparing(ShopOrderInfoVO::getUpdateTime).reversed());

        return shopOrderInfoVOS;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public int delOrderByOrderId(String orderId) {
        if (orderId == null || "".equals(orderId)) {
            return 0;
        }
        // 删除订单表数据
        int update = shopOrderMapper.delete(new UpdateWrapper<ShopOrder>()
                .eq("order_id", orderId)
        );
        if (update < 1) {
            throw new BusinessException("delete_order_failed");
        }
        //删除订单信息表
        shopOrderInfoMapper.delete(new UpdateWrapper<ShopOrderInfo>()
                .eq("order_id", orderId)
        );
        // 删除订单详情表数据
        return shopOrderDetailMapper.delete(new UpdateWrapper<ShopOrderDetail>().eq("order_id", orderId));
    }

    @Override
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public int changePrice(String token) {
        Claims dataFromToken = TokenUtil.getDataFromToken(token);
        String orderId = dataFromToken.get("orderId", String.class);
        BigDecimal discount = BigDecimal.valueOf(Double.parseDouble(dataFromToken.get("discount", String.class)));
        // 校验输入的金额是否大于等于0
        ValidationUtil.validatePositiveBigDecimal(discount, "invalid_amount");

        return shopOrderMapper.update(null, new LambdaUpdateWrapper<ShopOrder>()
                .eq(ShopOrder::getOrderId, orderId)
                .eq(ShopOrder::getOrderStatus, 0)
                .eq(ShopOrder::getDelFlag, 0)
                .set(ShopOrder::getDiscount, discount));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public boolean payOrder(String token) {

        Claims dataFromToken = TokenUtil.getDataFromToken(token);
        // 这里获取的是orderId的数组，因为多个不同店铺的商品一起下单的话会产生多个orderId，用“，”分隔
        List<String> orderIdArray = dataFromToken.get("orderIdArray", ArrayList.class);
        String uid1 = dataFromToken.get("uid", String.class);
        // 所有商品的总积分价格
        String payPointSumStr = dataFromToken.get("payPointSum", String.class);
        ValidationUtil.validateString(payPointSumStr, "pay_point_sum_required");
        BigDecimal payPointSum;
        try {
            payPointSum = new BigDecimal(payPointSumStr);
        } catch (NumberFormatException e) {
            throw new BusinessException("pay_point_sum_invalid_format");
        }
        ValidationUtil.validatePositiveBigDecimal(payPointSum, "pay_point_sum_negative");

        Date date = new Date();
        try {
            orderIdArray.stream().forEach(orderId -> {
                // 校验订单id是否已经存在，保证接口的幂等性，避免重复下单
                ShopOrder shopOrder = shopOrderMapper.selectOne(new QueryWrapper<ShopOrder>()
                        .eq("order_id", orderId)
                        .eq("order_status", 0));
                if (shopOrder == null) {
                    throw new BusinessException(PAY_ERROR);
                }
                // 订单状态、修改时间更新
                int update = shopOrderMapper.update(null, new UpdateWrapper<ShopOrder>()
                        .eq("order_id", orderId)
                        .set("order_status", 1)
                        .set("pay_time", date)
                        .set("update_time", date));
                //修改订单信息表
                update += shopOrderInfoMapper.update(null, new UpdateWrapper<ShopOrderInfo>()
                        .eq("order_id", orderId)
                        .set("order_time", date)
                        .set("update_time", date)
                        .set("order_status", 1));

                if (update < 2) {
                    throw new BusinessException(PAY_ERROR);
                }
                //增加商品销量
            });
            // 用户余额更新
            int uid = accountInfoMapper.updatePointBalanceByUid(payPointSum, uid1);
            if (uid < 1) {
                throw new BusinessException(PAY_ERROR);
            }
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public boolean payOrderCertificate(MultipartFile file, String token) {
        if (file.isEmpty()) {
            throw new BusinessException("file_required");
        }
        String fileName = file.getOriginalFilename();
        if ("".equals(fileName)) {
            throw new BusinessException("file_name_required");
        }
        String separator = File.separator;
        String postStr = fileName.substring(fileName.lastIndexOf(".") + 1);
        String preStr = StringUtil.generateShortId();
        fileName = "temp-" + preStr + "." + postStr;
        String ThumbnailPath = preStr + "." + postStr;
        File readPath = new File(Constants.PAYMENT_IMAG_PATH + separator);
        if (!readPath.isDirectory()) {
            readPath.mkdirs();
        }
        // 将文件复制到指定路径
        File destFile = new File(readPath.getAbsolutePath() + separator + fileName);
        // 解析token
        Claims dataFromToken = TokenUtil.getDataFromToken(token);
        String orderId = dataFromToken.get("orderId", String.class);
        String userId = dataFromToken.get("userId", String.class);


        // 获取订单详情
        ShopOrder shopOrder = shopOrderMapper.selectOne(new QueryWrapper<ShopOrder>()
                .eq("order_id", orderId));


        // 上传图片和改订单状态为2:提交凭证图片
        shopOrder.setCertificateImag("/images/payment_certificate/" + ThumbnailPath);
        shopOrder.setOrderStatus(1);
        // 更改订单状态和提交图片
        int update = shopOrderMapper.updateById(shopOrder);

        if (update < 1) {
            throw new BusinessException("submit_failed");
        }
        try {
            // 移动temp图片到目标文件夹
            FileCopyUtils.copy(file.getBytes(), destFile);
            String absolutePath = new File(Constants.PAYMENT_IMAG_PATH + separator + ThumbnailPath).getAbsolutePath();
            // 压缩图片
            Thumbnails.of(Constants.PAYMENT_IMAG_PATH + separator + fileName)
                    .size(300, 300)
                    .outputFormat(postStr)
                    .toFile(absolutePath);
            // 删除temp图片
            if (destFile.exists()) {
                destFile.delete();
            }

        } catch (Exception e) {
            if (destFile.exists()) {
                destFile.delete();
                throw new BusinessException("submit_failed");
            }
            e.printStackTrace();
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public Integer updateOrder(String orderId, Integer status) {
        //数据检查
        ValidationUtil.validateString(orderId, "order_id_required");

        shopOrderMapper.update(null, new LambdaUpdateWrapper<ShopOrder>()
                .eq(ShopOrder::getOrderId, orderId)
                .set(ShopOrder::getOrderStatus, status));
        //更新订单信息表
        return shopOrderInfoMapper.update(null, new LambdaUpdateWrapper<ShopOrderInfo>()
                .eq(ShopOrderInfo::getOrderId, orderId)
                .set(ShopOrderInfo::getOrderStatus, status));

    }

    @Override
    public ShopOrderDetailVO getOrderDetail(String orderId) {
        List<ShopOrderDetailVO> orderDetailVOList = shopOrderDetailMapper.getOrderDetail(orderId);
        // 获取其中一条数据
        ShopOrderDetailVO orderDetail = orderDetailVOList.get(0);
        if (orderDetail != null) {
            String addressAll = orderDetail.getAddress();
            //设置地址
            String address = addressAll.split(",")[1];
            orderDetail.setAddress(address);
            //设置收货人姓名
            orderDetail.setBuyerName(addressAll.split(",")[2]);
            //设置手机号
            orderDetail.setPhone(addressAll.split(",")[3]);
        }
        //设置商品列表

        return orderDetail;
    }

//    private void getOrderCommodityList(List<ShopOrderInfoVO> list) {
//        // 获取订单内的商品数据
//        list.stream()
//                .parallel()
//                .forEach(myshopOrderInfoVO -> {
//                    List<ShopOrderDetailDTO> commodityList = shopOrderDetailMapper.selectCommodityList(myshopOrderInfoVO.getOrderId());
//                    myshopOrderInfoVO.setCommodityList(commodityList);
//                });
//    }


    @Override
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public List<String> generateUnpaidOrder(String token) {
        // 解析token
        Claims dataFromToken = TokenUtil.getDataFromToken(token);
        String uid = dataFromToken.get("uid", String.class);
        String buyerDataId = dataFromToken.get("buyerDataId", String.class);
        String paymentId = dataFromToken.get("paymentId", String.class);

        // 根据buyerDataId查询用户收货地址、手机号和收货人姓名
        QueryWrapper<BuyerData> queryWrapper = new QueryWrapper<BuyerData>()
                .select("address", "phone", "user_name")
                .eq("buyer_data_id", buyerDataId)
                .eq("del_flag", 0);

        BuyerData buyerData = buyerDataMapper.selectOne(queryWrapper);

        String address = buyerData.getAddress();
        String phone = buyerData.getPhone();
        String userName = buyerData.getUserName();


        // 订单中的商品集合
        List<Object> shopOrderDetailDTOList = dataFromToken.get("itemOrderDetailDTOList", List.class);
        // 生成的订单id集合
        List<String> orderIdList = new ArrayList<>();
         /*由于Map中的参数get出来，并强转成其他类型时，它会先转换成LinkedHashMap，再尝试强转成其他的类。但是基本不会强转成功，
         所以会报 java.util.LinkedHashMap cannot be cast to*******这个错误。
         解决思路：从list中取出来的数据需要进行转化成json格式字符串，然后再将该json格式字符串转换成对象，这样就不会再出现报错情况，能成功遍历该list列表。
         */
        List<ShopOrderDetailDTO> detailList = shopOrderDetailDTOList.stream().map(shopOrderDetailDTO -> {
            // 将list中的数据转成json字符串
            String jsonObject = JSON.toJSONString(shopOrderDetailDTO);
            // 将json转成需要的对象
            return JSONObject.parseObject(jsonObject, ShopOrderDetailDTO.class);
        }).collect(Collectors.toList());
        // 这里将传递过来的商品集合根据shopId来划分订单范围，一个订单存储的数据要是同一个shop才行，这样子才能保证物流数据的正确性
        // detailMap用于存储shopId和对应的子集合
        Map<String, List<ShopOrderDetailDTO>> detailMap = new HashMap<>(detailList.size());
        detailList.stream().parallel().forEach(detail -> {
            String shopId = detail.getShopId();
            List<ShopOrderDetailDTO> sublist = detailMap.computeIfAbsent(shopId, k -> new ArrayList<>());
            sublist.add(detail);
        });
        // Map中的每一位元素都对应一个订单
        detailMap.forEach((key, commodityList) -> {
            // 获取一个订单的商品数据列表
            // 计算原总价
            BigDecimal originSum = commodityList.stream()
                    .map(detail -> {
                        Integer skuId = detail.getSkuId();
                        Sku sku = skuMapper.selectOne(new LambdaQueryWrapper<Sku>().eq(Sku::getId, skuId));

                        // 获取商品价格，并校验非负
                        BigDecimal price = sku.getPrice() != null ? sku.getPrice() : BigDecimal.ZERO;
                        ValidationUtil.validatePositiveBigDecimal(price, "product_price_negative");

                        // 获取商品数量，并校验非负
                        BigDecimal quantity = detail.getNumber() != null ? BigDecimal.valueOf(detail.getNumber()) : BigDecimal.ZERO;
                        ValidationUtil.validatePositiveBigDecimal(quantity, "product_quantity_negative");

                        return price.multiply(quantity);  // 计算单价 * 数量
                    })
                    .reduce(BigDecimal.ZERO, BigDecimal::add);  // 累加每个商品的总价

//            BigDecimal discountSum = commodityList.stream()
//                    .map(detail -> {
//                        // 获取商品数量，并校验非负
//                        Integer skuId = detail.getSkuId();
//                        Sku sku = skuMapper.selectOne(new LambdaQueryWrapper<Sku>().eq(Sku::getId, skuId));
//                        BigDecimal quantity = detail.getNumber() != null ? BigDecimal.valueOf(detail.getNumber()) : BigDecimal.ZERO;
//                        ValidationUtil.validatePositiveBigDecimal(quantity, "product_quantity_negative");
//
//                        // 获取商品折扣，并校验非负
//                        BigDecimal discount = sku.getDiscount() != null ? detail.getDiscount() : BigDecimal.ZERO;
//                        ValidationUtil.validatePositiveBigDecimal(discount, "product_discount_negative");
//
//                        return quantity.multiply(discount);  // 计算折扣金额
//                    })
//                    .reduce(BigDecimal.ZERO, BigDecimal::add);  // 累加每个商品的折扣金额


            // 生成订单id
            String orderId = StringUtil.generateShortId();
            // 记录订单id
            orderIdList.add(orderId);
            // 插入订单主题表数据
//            ShopOrder shopOrder = ShopOrder.builder().orderId(orderId).paymentId(paymentId).shopId(shopId).build();
            ShopOrder shopOrder = new ShopOrder(null, orderId, paymentId, originSum, null, key, uid,
                    buyerDataId + "," + address + "," + userName + "," + phone
                    , 0, new Date(), new Date(), 0);
            int insert = shopOrderMapper.insert(shopOrder);
            if (insert < 1) {
                throw new BusinessException(ERROR_MAG);
            }


            // 插入订单详情表数据
            commodityList
                    .forEach(shopOrderDetailDTO -> {
                        ShopOrderDetail shopOrderDetail = new ShopOrderDetail();
                        // 属性转移
                        BeanUtils.copyProperties(shopOrderDetailDTO, shopOrderDetail);
                        // 补全属性
                        shopOrderDetail.setOrderId(orderId);
                        shopOrderDetail.setCreateTime(new Date());
                        shopOrderDetail.setSkuId(shopOrderDetailDTO.getSkuId());
                        shopOrderDetail.setDelFlag(0);
                        Integer skuId = shopOrderDetailDTO.getSkuId();
                        shopOrderDetail.setPiPrice(skuMapper.selectOne(new LambdaQueryWrapper<Sku>().eq(Sku::getId, skuId)).getPiPrice());
                        ArrayList<String> strings = new ArrayList<>();
                        strings.add(shopOrderDetailDTO.getCommodityId());
                        ArrayList<Integer> skuIds = new ArrayList<>();
                        skuIds.add(shopOrderDetailDTO.getSkuId());
                        List<Sku> sku = skuMapper.selectByCommodityIdAndSkuId(strings, skuIds);
                        // 使用 ObjectMapper 转换为 JSON 字符串
                        ObjectMapper objectMapper = new ObjectMapper();
                        System.out.println(sku);
                        String json = null;
                        try {
                            json = objectMapper.writeValueAsString(sku.get(0).getCommoditySpec());
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                        shopOrderDetail.setCommoditySpecification(json);
                        // 修改商品展示图数据指向image表的id
//                        String imageId = imageMapper.selectImageIdByPath(shopOrderDetailDTO.getAvatarImag());
//                        shopOrderDetail.setAvatarImag(imageId);
                        // 插入数据库
                        int insertshopOrderDetail = shopOrderDetailMapper.insert(shopOrderDetail);
                        if (insertshopOrderDetail < 1) {
                            throw new BusinessException(ERROR_MAG);
                        }
                        //插入订单信息表
                        ShopOrderInfo shopOrderInfo = new ShopOrderInfo();
//            BeanUtils.copyProperties(shopOrder, shopOrderInfo);
                        shopOrderInfo.setCreateTime(new Date());
                        shopOrderInfo.setUpdateTime(new Date());
                        shopOrderInfo.setOrderStatus(0);

//                        shopOrderInfo.setTransactionAmount(originSum.subtract(discountSum));
                        shopOrderInfo.setTransactionAmount(shopOrderDetailDTO.getPrice());
                        shopOrderInfo.setNumber(shopOrderDetailDTO.getNumber());

                        shopOrderInfo.setCommoditySpecification(json);
                        shopOrderInfo.setCommodityId(shopOrderDetailDTO.getCommodityId());
                        shopOrderInfo.setOrderId(orderId);
                        shopOrderInfo.setUid(uid);
                        shopOrderInfo.setShopId(key);
                        shopOrderInfo.setDelFlag(0);
                        shopOrderInfo.setBuyerDataId(buyerDataId);
                        shopOrderInfoMapper.insert(shopOrderInfo);
//                        int update = shopCommodityInfoMapper.reduceStock(shopOrderDetailDTO.getNumber(), shopOrderDetailDTO.getCommodityId());
//                        if (update < 1) {
//                            throw new BusinessException(ERROR_MAG);
//                        }

                        // 扣减商品的剩余库存余额
                        //遍历commodityList
//                        for (ShopOrderDetailDTO commodity : commodityList) {
//                            Integer skuId = commodity.getSkuId();
//                            int update = skuMapper.reduceStock(shopOrderDetailDTO.getNumber(), skuId);
//                            if (update < 1) {
//                                throw new BusinessException(ERROR_MAG);
//                            }
//                        }
                    });
            //删除购物车包含订单的商品

            if (uid != null && commodityList != null && !commodityList.isEmpty()) {
                // 构建 SKU ID 集合
                List<Integer> skuIdList = commodityList.stream()
                        .map(ShopOrderDetailDTO::getSkuId)
                        .collect(Collectors.toList());


                // 构建 Commodity ID 集合
                List<String> commodityIdList = commodityList.stream()
                        .map(ShopOrderDetailDTO::getCommodityId)
                        .collect(Collectors.toList());

                // 检查 SKU ID 和 Commodity ID 是否非空
                if (!skuIdList.isEmpty() && !commodityIdList.isEmpty()) {
                    // 删除购物车包含订单的商品
                    shopCartMapper.delete(new LambdaQueryWrapper<ShopCart>()
                            .eq(ShopCart::getUserId, uid)
                            .in(ShopCart::getSkuId, skuIdList)
                            .in(ShopCart::getCommodityId, commodityIdList));
                }
            }

            //删除购物车缓存 格式为shop_cart_list::test888 其中test888为用户id
            redisTemplate.delete("shop_cart_list::" + uid);


            //更新订单中商品的库存
            commodityList.forEach(detail -> {
                // 获取商品id
                String commodityId = detail.getCommodityId();
                Integer skuId = detail.getSkuId();
                // 获取商品数量
                Integer number = detail.getNumber();
                // 扣减库存
//                int update = shopCommodityMapper.reduceStock(number, commodityId);
                Integer update = skuMapper.update(
                        null,
                        new UpdateWrapper<Sku>()
                                .eq("id", skuId)
                                .eq("commodity_id", commodityId)
                                .ge("inventory", 1)  // 确保库存大于等于 1
                                .setSql("inventory = inventory - " + number)  // 执行库存扣减
                );
                if (update < 1) {
                    throw new BusinessException(ERROR_MAG);
                }
                //更新商品销量
                shopCommodityMapper.update(null, new UpdateWrapper<ShopCommodity>()
                        .eq("commodity_id", commodityId)
                        .setSql("sales = sales + " + number)
                        .setSql("inventory = inventory - " + number));

                //删除缓存
                redisTemplate.delete("shop_commodity_stock::" + commodityId);
            });

            rabbitTemplate.convertAndSend(OrderQueueConfig.SHOP_ORDER_EXCHANGE, "shop", "shop_" + orderId,
                    message -> {
                        message.getMessageProperties().setExpiration("600000");
                        log.error("msg:{}", message);
                        return message;
                    });

        });
        return orderIdList;
    }

    @Override
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public void deleteFailOrders() {
        shopOrderMapper.update(null, new UpdateWrapper<ShopOrder>()
                .eq("order_status", 3)
                .eq("del_flag", 0)
                .set("del_flag", 1)
                .set("order_status", 3)
                .apply("TIMESTAMPDIFF(SECOND, create_time, NOW()) >= 600")
                .set("update_time", new Date()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public void failOrder(String orderId) {
        // 死信队列到点了就调该失效方法，通过orderId对应的订单的状态来确定是否使其失效
        boolean flag = shopOrderMapper.exists(new LambdaUpdateWrapper<ShopOrder>()
                .eq(ShopOrder::getOrderId, orderId)
                .eq(ShopOrder::getDelFlag, 0)
                .eq(ShopOrder::getOrderStatus, 0));
        if (!flag) {
            // 不存在说明并没有
            return;
        }
        // 获取订单内的商品数据
        List<ShopOrderDetailDTO> shopOrderDetailDTOS = shopOrderDetailMapper.selectCommodityList(orderId);
        // 释放锁住的商品库存
        shopOrderDetailDTOS.forEach(shopOrderDetailDTO -> {
//            int i = shopCommodityInfoMapper.addStock(shopOrderDetailDTO.getNumber(), shopOrderDetailDTO.getCommodityId());
            int update = 0;
            try {
                update = skuMapper.update(null, new UpdateWrapper<Sku>()
                        .eq("id", shopOrderDetailDTO.getSkuId())
                        .setSql("inventory = inventory + " + shopOrderDetailDTO.getNumber()));
            } catch (Exception e) {
                System.out.println(e);
            }

            if (update < 1) {
                log.error("释放库存失败");
                throw new BusinessException("update_failed");
            }
        });
        // 修改订单状态为失效状态
        int i1 = shopOrderMapper.update(null, new UpdateWrapper<ShopOrder>()
                .eq("order_id", orderId)
                .set("order_status", 3)
                .set("update_time", new Date()));
        shopOrderInfoMapper.update(null, new UpdateWrapper<ShopOrderInfo>()
                .eq("order_id", orderId)
                .set("order_status", 3)
                .set("update_time", new Date()));
        if (i1 < 1) {
            throw new BusinessException("update_failed");
        }
    }

    @Override
    @CacheEvict(value = Constants.SHOP_ORDER_LIST_KEY, allEntries = true)
    public int completedOrder(String orderId) {
        return shopOrderMapper.update(null, new UpdateWrapper<ShopOrder>()
                .eq("order_id", orderId)
                .set("order_status", 2)
                .set("update_time", new Date()));
    }


//    public PageDataVO getOrderListByShopId(GetOrderDataDto getOrderDataDto) {
//        getOrderDataDto.setCurrentPage((getOrderDataDto.getCurrentPage() - 1) * getOrderDataDto.getPageSize());
//        List<OrderListVO> voList = shopOrderInfoMapper.getOrderListByShopId(getOrderDataDto);
//        Integer count = shopOrderInfoMapper.getOrderListCountByShopId(getOrderDataDto);
//        return new PageDataVO(count,voList);
//    }


}
